home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’87 / Source ƒ.sit / Source ƒ / C ƒ / TRANS-LSC / ManyWind.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-10-24  |  6.5 KB  |  271 lines  |  [TEXT/KAHL]

  1. /*
  2.     ManyWind TransSkel demonstration
  3.     
  4.     This application allows up to twenty windows to be created at once,
  5.     with the New item under the File menu.  The name of each window
  6.     appears under the Windows menu (which is not created until at least
  7.     one window exists).  Selecting the window name from the Windows menu
  8.     brings the window to the front.  For every window created, Skel is
  9.     told to create a new handler.  If the window's close box is clicked,
  10.     the handler removes the window name from the Windows menu, disposes
  11.     of the window, and removes itself from the window handler list.  If
  12.     the window was the last window, the Windows menu handler removes
  13.     itself from the menu handler list.
  14.     
  15.     When the first window is created, a Color menu also appears.  This
  16.     allows the color of the content region of the frontmost window to
  17.     be changed.  It goes away when the last window is closed.
  18.     
  19.     To quit, select Quit from the File menu or type command-Q.
  20.  
  21.     ManyWind demonstrates dynamic window and menu creation and disposal.
  22.     It also shows how handler procedures may be shared among handlers
  23.     for different windows.
  24.  
  25.     The project should include this file, TransSkel.c (or a project
  26.     built from TransSkel.c), and MacTraps.
  27.  
  28.     28 June 1986        Paul DuBois
  29. */
  30.  
  31. # include    <WindowMgr.h>
  32. # include    <MenuMgr.h>
  33.  
  34. # define    nil    0L
  35. # define    maxWind    20    /* maximum number of windows existing at once */
  36.  
  37.  
  38. enum                /* menu numbers */
  39. {
  40.     aMenuNum = 1,    /* Apple menu */
  41.     fMenuNum,        /* File menu */
  42.     wMenuNum,        /* Windows menu */
  43.     cMenuNum        /* Color menu */
  44. };
  45.  
  46.  
  47. enum                /* File menu item numbers */
  48. {
  49.     new = 1,
  50.     /* --- */
  51.     quit = 3
  52. };
  53.  
  54. enum                /* Color menu items numbers */
  55. {
  56.     cWhite = 1,
  57.     cLtGray,
  58.     cGray,
  59.     cDkGray,
  60.     cBlack
  61. };
  62.  
  63.  
  64. MenuHandle    fileMenu;
  65. MenuHandle    windowMenu;
  66. MenuHandle    colorMenu;
  67.  
  68. int            windCount = 0;    /* number of currently existing windows */
  69. long        windNum = 0;    /* id of last window created */
  70.  
  71. int            DoWindowMenu(), DoColorMenu(), DoMClobber();
  72.  
  73.  
  74. DoWUpdate ()
  75. {
  76. GrafPtr    thePort;
  77.  
  78.  
  79.     GetPort (&thePort);
  80.     EraseRect (&thePort->portRect);    /* repaint w/background pattern */
  81. }
  82.  
  83.  
  84. /*
  85.     Mouse was clicked in close box.  Remove the window handler (which
  86.     causes the window to be disposed of), and delete the window title
  87.     from the Windows menu.  If the window was the last one, delete the
  88.     Windows and Color menus entirely.
  89.  
  90.     Skel makes sure the port is pointing to the appropriate window, so
  91.     this procedure can determine which window had its close box clicked,
  92.     without being told explicitly.
  93. */
  94.  
  95. DoWClose ()
  96. {
  97. GrafPtr        thePort;
  98. MenuHandle    m;
  99. int            i, mItems;
  100. Str255        iTitle, wTitle;
  101.  
  102.     GetPort (&thePort);                /* grafport of window to be closed */
  103.     GetWTitle ((WindowPtr) thePort, wTitle);
  104.     SkelRmveWind ((WindowPtr) thePort);
  105.     if (--windCount == 0)
  106.     {
  107.         SkelRmveMenu (windowMenu);    /* last window - clobber menus */
  108.         SkelRmveMenu (colorMenu);
  109.     }
  110.     else
  111.     {
  112.         /* just take out of menu */
  113.         m = NewMenu (wMenuNum, "\pWindows");
  114.         for (i = 1, mItems = CountMItems (windowMenu); i <= mItems; ++i)
  115.         {
  116.             GetItem (windowMenu, i, iTitle);
  117.             if (!EqualString (iTitle, wTitle, false, true))
  118.                 AppendMenu (m, iTitle);
  119.         };
  120.         SkelRmveMenu (windowMenu);    /* remove old Windows menu */
  121.         windowMenu = m;                /* and install new one */
  122.         SkelMenu (windowMenu, DoWindowMenu, DoMClobber);
  123.     }
  124.     EnableItem (fileMenu, new);    /* can always create at least one more now */
  125. }
  126.  
  127.  
  128. /*
  129.     Dispose of window.  Skel makes sure the port is pointing to the
  130.     appropriate window, so this procedure can determine which window
  131.     is to be disposed, of without being told explicitly.
  132. */
  133.  
  134. DoWClobber ()
  135. {
  136. GrafPtr    thePort;
  137.  
  138.     GetPort (&thePort);                /* grafport of window to dispose of */
  139.     DisposeWindow ((WindowPtr) thePort);
  140. }
  141.  
  142.  
  143. DoMClobber (theMenu)
  144. MenuHandle    theMenu;
  145. {
  146.     DisposeMenu (theMenu);
  147. }
  148.  
  149.  
  150. /*
  151.     Make new window.  Locate at (100, 100) if no other windows, else
  152.     offset slightly from front window.  The window title is the next
  153.     window number (1, 2, 3, ...).  If this is the first window, create
  154.     the Windows and Color menus.  Add the window title as the last item
  155.     of the Windows menu.
  156.  
  157.     If the maximum window count has been reached, disable New in the
  158.     File menu.
  159. */
  160.  
  161.  
  162. MakeWindow ()
  163. {
  164. WindowPtr    w;
  165. Rect        r, r2;
  166. Str255        s;
  167.  
  168.     SetRect (&r, 0, 0, 200, 150);
  169.     if ((w = FrontWindow ()) == nil)
  170.         OffsetRect (&r, 100, 100);
  171.     else
  172.     {
  173.         r2 = w->portBits.bounds;
  174.         OffsetRect (&r, 20 - r2.left, 20 - r2.top);
  175.         if (r.left > 480 || r.top > 300)    /* keep on screen */
  176.             OffsetRect (&r, 40 - r.left, 40 - r.top);
  177.     }
  178.     NumToString (++windNum, s);
  179.     w = NewWindow (nil, &r, s, true, documentProc, -1L, true, 0L);
  180.     SkelWindow (w,
  181.                 nil,        /* mouseclicks */
  182.                 nil,        /* key clicks */
  183.                 DoWUpdate,    /* updates */
  184.                 nil,        /* activate/deactivate events */
  185.                 DoWClose,    /* close window, remove from menu */
  186.                 DoWClobber,    /* dispose of window */
  187.                 nil,        /* idle proc */
  188.                 false);        /* irrelevant, since no idle proc */
  189.  
  190.     if (windCount++ == 0)    /* if first window, create new menus */
  191.     {
  192.         colorMenu = NewMenu (cMenuNum, "\pColor");
  193.         AppendMenu (colorMenu, "\pWhite;Light Gray;Gray;Dark Gray;Black");
  194.         SkelMenu (colorMenu, DoColorMenu, DoMClobber);
  195.         windowMenu = NewMenu (wMenuNum, "\pWindows");
  196.         SkelMenu (windowMenu, DoWindowMenu, DoMClobber);
  197.     }
  198.     AppendMenu (windowMenu, s);
  199.     if (windCount == maxWind)
  200.         DisableItem (fileMenu, new);
  201.  
  202. }
  203.  
  204.  
  205. DoFileMenu (item)
  206. int        item;
  207. {
  208.  
  209.     switch (item)
  210.     {
  211.         case quit: SkelWhoa (); break;    /* tell SkelMain to quit */
  212.         case new: MakeWindow (); break;    /* make a new window */
  213.     }
  214. }
  215.  
  216.  
  217. DoWindowMenu (item)
  218. int        item;
  219. {
  220. Str255        iTitle, wTitle;
  221. WindowPeek    w;
  222.  
  223.     GetItem (windowMenu, item, iTitle);    /* get window name */
  224.     for (w = (WindowPeek) FrontWindow (); w != nil; w = w->nextWindow)
  225.     {
  226.         GetWTitle (w, wTitle);
  227.         if (EqualString (iTitle, wTitle, false, true))
  228.         {
  229.             SelectWindow (w);
  230.             break;
  231.         }
  232.     }
  233. }
  234.  
  235.  
  236. /*
  237.     Change the background pattern of the frontmost window.  Ignore
  238.     if the front window is a DA window.
  239. */
  240.  
  241. DoColorMenu (item)
  242. int        item;
  243. {
  244. WindowPtr    w;
  245.  
  246.     w = FrontWindow ();
  247.     if (((WindowPeek) w)->windowKind < 0) return;    /* front is DA window */
  248.     switch (item)
  249.     {
  250.         case cWhite:    BackPat (white); break;
  251.         case cLtGray:    BackPat (ltGray); break;
  252.         case cGray:        BackPat (gray); break;
  253.         case cDkGray:    BackPat (dkGray); break;
  254.         case cBlack:    BackPat (black); break;
  255.     }
  256.     EraseRect (&w->portRect);
  257. }
  258.  
  259.  
  260. main ()
  261. {
  262.     SkelInit ();                                /* initialize */
  263.     SkelApple (nil, nil);                        /* handle desk accessories */
  264.     fileMenu = NewMenu (fMenuNum, "\pFile");    /* make File menu handler */
  265.     AppendMenu (fileMenu, "\pNew/N;(-;Quit/Q");
  266.     SkelGrowBounds (nil, 50, 10, 500, 300);
  267.     SkelMenu (fileMenu, DoFileMenu, DoMClobber);
  268.     SkelMain ();                                /* loop 'til Quit selected */
  269.     SkelClobber ();                                /* clean up */
  270. }
  271.